package com.sparrow.utils;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.channels.FileLock;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import com.sparrow.constant.*;
import com.sparrow.core.Log;
import com.sparrow.enums.OPERATION_RESULT;

public class HttpClient {
	public static String getRedirectUrl(String pageUrl) {
		try {
			URL url = new URL(pageUrl);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.connect();
			connection.disconnect();
			return connection.getURL().toString();
		} catch (Exception e) {
			Log.getInstance().error(e);
		}
		return null;
	}

	public static int getResponseCode(String pageUrl) {
		try {
			URL url = new URL(pageUrl);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.connect();
			connection.disconnect();
			return connection.getResponseCode();
		} catch (Exception e) {
			Log.getInstance().error(e);
		}
		return 500;
	}

	public static String get(String pageUrl) {
		return get(pageUrl, null);
	}

	public static String get(String pageUrl, String charset) {
		if (StringUtil.isNullOrEmpty(charset)) {
			charset = "UTF-8";
		}
		HttpURLConnection connection = null;
		try {
			URL url = new URL(pageUrl);
			connection = (HttpURLConnection) url.openConnection();
			connection.setConnectTimeout(60 * 1000);
			connection.setReadTimeout(60 * 1000);
			BufferedReader br = new BufferedReader(new InputStreamReader(
					connection.getInputStream(), charset));
			connection.connect();
			StringBuffer content = new StringBuffer();
			String line = null;
			while ((line = br.readLine()) != null) {
				content.append(line);
				content.append("\r\n");
			}
			connection.disconnect();
			return content.toString().trim();
		} catch (Exception e) {
			return null;
		}
	}

	public static String postBody(String pageUrl, String data) {
		return post(pageUrl, data, "text/html");
	}

	public static String post(String pageUrl, String data) {
		return post(pageUrl, data, null);
	}

	private static String post(String pageUrl, String data, String contentType) {
		StringBuffer buffer = new StringBuffer();
		HttpURLConnection httpUrlConnction = null;
		try {
			URL url = new URL(pageUrl);
			httpUrlConnction = (HttpURLConnection) url.openConnection();
			httpUrlConnction.setRequestMethod("POST");
			httpUrlConnction.setRequestProperty("Accept-Charset", "utf-8");
			if (StringUtil.isNullOrEmpty(contentType)) {
				httpUrlConnction.setRequestProperty("Content-Type",
						"application/x-www-form-urlencoded");
			} else {
				httpUrlConnction
						.setRequestProperty("Content-type", "text/html");

			}

			httpUrlConnction.setDoOutput(true);
			httpUrlConnction.setDoInput(true);
			httpUrlConnction.setConnectTimeout(30000);
			httpUrlConnction.setReadTimeout(30000);
			httpUrlConnction.connect();
			PrintWriter out = new PrintWriter(
					httpUrlConnction.getOutputStream());
			out.print(data);
			out.flush();
			out.close();
			int responseCode = 0;
			responseCode = httpUrlConnction.getResponseCode();
			if (responseCode == 200) {
				InputStream responseStream = httpUrlConnction.getInputStream();
				BufferedReader in = new BufferedReader(new InputStreamReader(
						responseStream));
				String line = "";
				while ((line = in.readLine()) != null) {
					buffer.append(line);
				}
			} else {
				buffer.append(OPERATION_RESULT.FAIL.toString() + "|"
						+ responseCode);
			}
			httpUrlConnction.disconnect();
		} catch (Exception e) {
			Log.getInstance().error(e);
		}
		return buffer.toString();
	}

	/**
	 * 下载二进制文件
	 * 
	 * @author zhanglizhi
	 * @date 2013-1-13
	 * @version 1.0
	 * @param fileUrl
	 * @param fileFullPath
	 * @return
	 */
	public static boolean downloadFile(String fileUrl, String fileFullPath) {
		URL url = null;
		FileOutputStream fos = null;
		BufferedInputStream bis = null;
		HttpURLConnection httpURLConnection = null;
		int BUFFER_SIZE = 1024;
		int totleSize = 0;
		try {

			byte[] buf = new byte[BUFFER_SIZE];
			int size = 0;
			// 建立链接
			url = new URL(fileUrl);
			httpURLConnection = (HttpURLConnection) url.openConnection();
			// 连接指定的资源
			httpURLConnection.connect();
			// 获取网络输入流
			bis = new BufferedInputStream(httpURLConnection.getInputStream());

			String descDirectoryPath = fileFullPath.substring(0,
					fileFullPath.lastIndexOf('/') + 1);
			File descDirectory = new File(descDirectoryPath);
			if (!descDirectory.exists()) {
				descDirectory.mkdirs();
			}
			// 建立文件
			fos = new FileOutputStream(fileFullPath);
			System.out.println("正在获取链接[" + fileUrl + "]的内容...\n将其保存为文件["
					+ fileFullPath + "]");
			// 保存文件
			while ((size = bis.read(buf)) != -1) {
				fos.write(buf, 0, size);
				totleSize += size;
				System.out.println("已下载:" + totleSize);
			}
			return true;

		} catch (Exception e) {
			Log.getInstance().error(e);
			return false;
		}

		finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
				}
			}
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
				}
			}
			if (httpURLConnection != null) {
				httpURLConnection.disconnect();
			}
		}
	}

	/**
	 * 下载文本文件
	 * 
	 * @author zhanglizhi
	 * @date 2013-1-13
	 * @version 1.0
	 * @param url
	 * @param htmlFileName
	 * @return
	 */
	public static boolean downloadPage(String url, String htmlFileName,
			String charset) {
		try {
			if (StringUtil.isNullOrEmpty(charset)) {
				charset = "UTF-8";
			}
			String html = get(url, charset);
			if (!html.trim().startsWith(FILE.ERROR_STATIC_HTML)) {
				String descDirectoryPath = htmlFileName.substring(0,
						htmlFileName.lastIndexOf('/') + 1);
				File descDirectory = new File(descDirectoryPath);
				if (!descDirectory.exists()) {
					descDirectory.mkdirs();
				}
				FileOutputStream fos = new FileOutputStream(htmlFileName, false);
				FileLock fl = fos.getChannel().tryLock();
				OutputStreamWriter os = new OutputStreamWriter(fos, charset);
				BufferedWriter bw = new BufferedWriter(os);
				if (fl != null && fl.isValid()) {
					bw.write(html);
					fl.release();
				}
				bw.flush();
				os.flush();
				fos.flush();
				bw.close();
				fos.close();
				os.close();
			} else {
				Log.getInstance().warm(FILE.ERROR_STATIC_HTML + url);
			}
			return true;
		} catch (Exception e) {
			Log.getInstance().error(e);
			return false;
		}
	}

	public static Map<String, String> deSerialJson(String json) {
		// 去掉{
		json = json.substring(0, 1);
		// 去掉}
		json = json.substring(json.length() - 1);
		Map<String, String> map = new TreeMap<String, String>();
		String[] KeyValues = json.split("\\,");
		for (int i = 0; i < KeyValues.length; i++) {
			String[] keyValue = KeyValues[i].split("\\:");
			String key = keyValue[0];
			if (key.contains("\"")) {
				key.replace("\"", "");
			}
			String value = keyValue[1];
			if (value.contains("\"")) {
				value.replace("\"", "");
			}
			map.put(key, value);
		}
		return map;
	}

	public static Map<String, String> deSerialParameters(String request_token) {
		Map<String, String> tokens = new TreeMap<String, String>();
		request_token += "&";
		while (request_token.length() > 0) {
			String key_value = request_token.substring(0,
					request_token.indexOf("&"));
			String key = key_value.substring(0, key_value.indexOf("="));
			String value = key_value.substring(key_value.indexOf("=") + 1,
					key_value.length());
			tokens.put(key, value);
			request_token = request_token.substring(
					request_token.indexOf("&") + 1, request_token.length());
		}
		return tokens;
	}

	public static String serialParameters(Map<String, String> parameters,
			boolean isEncodeAll) {
		StringBuffer serialParameters = new StringBuffer();
		Set<String> parameterKey = parameters.keySet();
		Iterator<String> iterator = parameterKey.iterator();
		while (iterator.hasNext()) {
			String key = iterator.next();
			String value = parameters.get(key);
			if (!isEncodeAll) {
				try {
					serialParameters.append(key + "="
							+ URLEncoder.encode(value, "UTF-8"));
				} catch (UnsupportedEncodingException e) {
				}

			} else {
				serialParameters.append(key + "=" + value);
			}
			serialParameters.append("&");
		}
		String strSerialParameters = serialParameters.deleteCharAt(
				serialParameters.length() - 1).toString();
		if (isEncodeAll) {
			try {
				strSerialParameters = URLEncoder.encode(strSerialParameters,
						"UTF-8");
			} catch (UnsupportedEncodingException e) {
			}
		}
		return strSerialParameters;
	}

	public static void clearNginxCache(String url) {
		String rootPath = Config.getValueInCache(CONFIG.ROOT_PATH);
		if (!url.startsWith(rootPath)) {
			url = rootPath + url;
		}
		HttpClient.get(url);
	}
}
